﻿using Engine;
using GameEntitySystem;
using System;
using System.Collections.Generic;
using System.IO;
using TemplatesDatabase;

namespace Game
{
    /// <summary>
    /// 命令方块系统
    /// </summary>
    public class SubsystemCommand : Subsystem
    {
        private static Dictionary<string, Func<CommandData, SubmitResult>> m_functions = new Dictionary<string, Func<CommandData, SubmitResult>>();

        private static Dictionary<string, Func<CommandData, SubmitResult>> m_conditions = new Dictionary<string, Func<CommandData, SubmitResult>>();

        public ComponentPlayer m_componentPlayer;

        public GameMode m_gameMode;

        public bool m_canWorking = true;

        public static bool MessageTips;

        public static bool ChartletDraw;

        public static bool InteractEnable;

        public override void Load(ValuesDictionary valuesDictionary)
        {
            if (!valuesDictionary.ContainsKey("Class")) return;
            string className = valuesDictionary.GetValue<string>("Class");
            if (className != "Game.SubsystemCommand") return;
            MessageTips = valuesDictionary.GetValue<bool>("MessageTips");
            ChartletDraw = valuesDictionary.GetValue<bool>("ChartletDraw");
            InteractEnable = valuesDictionary.GetValue<bool>("InteractEnable");
            AddFunction("moremode", delegate (CommandData commandData)
            {
                //moremode type:default
                if (commandData.Type == "default")
                {
                    //暂无
                }
                //moremode type:notips con:true
                else if (commandData.Type == "notips")
                {
                    bool con = (bool)commandData.GetValue("con");
                    MessageTips = !con;
                }
                //moremode type:nochartlet con:true
                else if (commandData.Type == "nochartlet")
                {
                    bool con = (bool)commandData.GetValue("con");
                    ChartletDraw = !con;
                }
                //moremode type:nointeract con:true
                else if (commandData.Type == "nointeract")
                {
                    bool con = (bool)commandData.GetValue("con");
                    InteractEnable = !con;
                }
                return SubmitResult.Success;
            });
        }

        public override void Save(ValuesDictionary valuesDictionary)
        {
            if (!valuesDictionary.ContainsKey("Class")) return;
            string className = valuesDictionary.GetValue<string>("Class");
            if (className != "Game.SubsystemCommand") return;
            valuesDictionary.SetValue("MessageTips", MessageTips);
            valuesDictionary.SetValue("ChartletDraw", ChartletDraw);
            valuesDictionary.SetValue("InteractEnable", InteractEnable);
        }

        public override void OnEntityAdded(Entity entity)
        {
            ComponentPlayer player = entity.FindComponent<ComponentPlayer>();
            if (player != null)
            {
                m_componentPlayer = player;
                m_gameMode = m_componentPlayer.m_subsystemGameInfo.WorldSettings.GameMode;
            }
        }

        public override void Dispose()
        {
            m_functions.Clear();
            m_conditions.Clear();
        }

        public void AddFunction(string name, Func<CommandData, SubmitResult> action)
        {
            if (!m_functions.ContainsKey(name))
            {
                m_functions.Add(name, action);
            }
            else
            {
                m_functions[name] += action;
            }
        }

        public void AddCondition(string name, Func<CommandData, SubmitResult> action)
        {
            if (!m_conditions.ContainsKey(name))
            {
                m_conditions.Add(name, action);
            }
            else
            {
                m_conditions[name] += action;
            }
        }

        public SubmitResult Submit(string name, CommandData commandData, bool Judge)
        {
            if (!m_canWorking) return SubmitResult.Fail;
            Dictionary<string, Func<CommandData, SubmitResult>> commands = (!Judge) ? m_functions : m_conditions;
            if (commands.TryGetValue(name, out Func<CommandData, SubmitResult> action))
            {
                if (!commandData.Valid) return SubmitResult.Invalid;
                if (commandData.OutRange) return SubmitResult.OutRange;
                try
                {
                    return action.Invoke(commandData);
                }
                catch (Exception e)
                {
                    Log.Warning("CommandManager:" + e.Message);
                    return SubmitResult.Exception;
                }
            }
            return SubmitResult.NoFound;
        }

        public void ShowSubmitTips(string tip, bool onlyError = false, SubmitResult result = SubmitResult.Success, CommandData commandData = null)
        {
            if (!MessageTips) return;
            if (onlyError)
            {
                string errorposition = string.Format(";\n发生错误的命令方块位置:({0},{1},{2})", commandData.Position.X, commandData.Position.Y, commandData.Position.Z);
                switch (result)
                {
                    case SubmitResult.Exception: m_componentPlayer?.ComponentGui.DisplaySmallMessage("错误:提交的" + commandData.Name + "指令发生异常，请重新编辑" + errorposition, Color.Yellow, false, false); break;
                    case SubmitResult.NoFound: m_componentPlayer?.ComponentGui.DisplaySmallMessage("错误:提交的" + commandData.Name + "指令不存在，请核对指令名称" + errorposition, Color.Yellow, false, false); break;
                    case SubmitResult.Invalid: m_componentPlayer?.ComponentGui.DisplaySmallMessage("错误:提交的" + commandData.Name + "指令存在问题，请重新编辑" + errorposition, Color.Yellow, false, false); break;
                    case SubmitResult.OutRange: m_componentPlayer?.ComponentGui.DisplaySmallMessage("错误:提交的" + commandData.Name + "指令存在参数超出范围，请纠正数值" + errorposition, Color.Yellow, false, false); break;
                    case SubmitResult.Limit: m_componentPlayer?.ComponentGui.DisplaySmallMessage("错误:挑战或残酷模式不支持" + commandData.Name + "指令" + errorposition, Color.Yellow, false, false); break;
                    default: break;
                }
            }
            else
            {
                if (result == SubmitResult.Success)
                {
                    m_componentPlayer?.ComponentGui.DisplaySmallMessage("提示:" + tip, Color.Yellow, false, false);
                }
            }
        }

        public void ShowEditedTips(string tip)
        {
            if (string.IsNullOrEmpty(tip)) return;
            m_componentPlayer?.ComponentGui.DisplaySmallMessage("提示：" + tip, Color.Yellow, false, false);
        }
    }
}